package com.cqupt.scanning.system.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.scanning.handler.exception.MyException;
import com.cqupt.scanning.system.acl.entity.AclUser;
import com.cqupt.scanning.system.acl.entity.AclUserRole;
import com.cqupt.scanning.system.acl.service.AclUserService;
import com.cqupt.scanning.system.admin.entity.Department;
import com.cqupt.scanning.system.admin.entity.DeviceFoot;
import com.cqupt.scanning.system.admin.entity.DeviceThree;
import com.cqupt.scanning.system.admin.entity.Organization;
import com.cqupt.scanning.system.admin.entity.dto.DepartmentDTO;
import com.cqupt.scanning.system.admin.entity.dto.DeviceDTO;
import com.cqupt.scanning.system.admin.entity.dto.OrganizationDTO;
import com.cqupt.scanning.system.admin.mapper.OrganizationMapper;
import com.cqupt.scanning.system.admin.service.DepartmentService;
import com.cqupt.scanning.system.admin.service.DeviceFootService;
import com.cqupt.scanning.system.admin.service.DeviceThreeService;
import com.cqupt.scanning.system.admin.service.OrganizationService;
import com.cqupt.scanning.system.file.helper.FilePathConfig;
import com.cqupt.scanning.system.utils.result.R;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 宋宝梁
 * @since 2021-07-06
 */
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements OrganizationService {


    @Lazy
    @Autowired
    private DeviceFootService deviceFootService;
    @Autowired
    private DepartmentService departmentService;
    @Lazy
    @Autowired
    private DeviceThreeService deviceThreeService;
    @Autowired
    private AclUserService aclUserService;

    @Autowired
    private FilePathConfig filePathConfig;



    @Override
    public R insert(Organization organization) {
        String orgNum = organization.getOrgNum();
        if (orgNum == null || StrUtil.hasBlank(orgNum)) return R.error().message("机构编码不能为空");

        Integer count = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_num", orgNum));
        if (count > 0) return R.error().message("机构编码已经存在");

        baseMapper.insert(organization);
        return R.ok().data("orgId", organization.getId());
    }

    @SneakyThrows
    @Override
    public R insert(HttpServletRequest request){
        Organization organization = new Organization();
        String orgName = request.getParameter("orgName");
//        String orgNum = request.getParameter("orgNum");
        String contactPersonPhone = request.getParameter("contactPersonPhone");
        String orgContactPerson = request.getParameter("orgContactPerson");
        String orgAddress = request.getParameter("orgAddress");

        Integer count = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_name",orgName));
        if (count > 0) return R.error().message("机构名称已经存在");
        String orgNumCreateTime = new SimpleDateFormat("MMddyyyyHHmmssS").format(System.currentTimeMillis());
        //标识符+时间戳+0.01重复概率的随机数 1+17+2=20位
        String orgNum = "H" + orgNumCreateTime+String.format("%02d", new Random().nextInt(100));
        Integer count1 = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_num",orgNum));
        if (count1 > 0) return R.error().message("机构编码已经存在，请联系管理员！");
        organization.setOrgName(orgName)
                .setOrgNum(orgNum)
                .setContactPersonPhone(contactPersonPhone)
                .setOrgContactPerson(orgContactPerson)
                .setOrgAddress(orgAddress);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("orgIconPath");
            if(file!=null){
                Date date = new Date();
                SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
                //获取上传图片的名称
                String orgIconPath = System.getProperty("user.dir")+ File.separator+filePathConfig.getOrgPictureDir()+File.separator+orgName+"_"+orgNum+File.separator+formatter.format(date)+File.separator+file.getOriginalFilename();
                File iconFile = new File(orgIconPath);
                if(!iconFile.exists())iconFile.mkdirs();//不存在的话，就开辟一个空间
                //将上传的文件存储
                file.transferTo(iconFile);
                organization.setOrgIconPath(orgIconPath);
            }
            baseMapper.insert(organization);
            return R.ok().message("添加成功").data("orgId", organization.getId());
    }

    @Override
    public R getAll(Page<Organization> page, String query) {
        IPage<Organization> organizationIPage = baseMapper.selectPage(page,
                new QueryWrapper<Organization>()
                        .isNotNull("org_num")
                        .like("org_name", query));
        return R.ok().data("orgs", organizationIPage);
    }

    @Override
    public R getDepAndDevById(Integer id) {
        Organization organizationFoot = baseMapper.getDepAndDevFootById(id);

        OrganizationDTO orgDTO = new OrganizationDTO();
        BeanUtils.copyProperties(organizationFoot, orgDTO);
        List<DepartmentDTO> departments = orgDTO.getDepartments();

        Organization organizationThree = baseMapper.getDepAndDevThreeById(id);
        List<DepartmentDTO> departments_three = organizationThree.getDepartments();

        for (DepartmentDTO departmentDTO : departments_three) {
            for (DepartmentDTO department : departments) {
                if (departmentDTO.getId().equals(department.getId())) {
                    List<DeviceDTO> devices = department.getDevices();
                    List<DeviceDTO> _devices = departmentDTO.getDevices();
                    for(DeviceDTO threeDevice : _devices){
                         AclUser aclUser = aclUserService.getOne(new QueryWrapper<AclUser>().eq("id", threeDevice.getUserId()));
                         String username = aclUser.getUsername();
                         threeDevice.setUsername(username);
                    }
                    for(DeviceDTO footDevice : devices){
                        AclUser aclUser = aclUserService.getOne(new QueryWrapper<AclUser>().eq("id", footDevice.getUserId()));
                        String username = aclUser.getUsername();
                        footDevice.setUsername(username);
                    }
                    devices.addAll(_devices);
                }
            }
        }
        return R.ok().data("organization", orgDTO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public R removeById(Integer orgId) {
        try {
            Organization organization = baseMapper.selectOne(new QueryWrapper<Organization>().eq("id",orgId).select("org_num"));
            Department department = departmentService.getOne(new QueryWrapper<Department>().eq("org_num",organization.getOrgNum()));
            if(department == null)
            {
                baseMapper.deleteById(orgId);
            }
            else {
                List<Department> departmentList = departmentService.list(new QueryWrapper<Department>().eq("org_num", organization.getOrgNum()));
                List<Integer> departmentIds = departmentList.stream().map(Department::getId).collect(Collectors.toList());

                DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().eq("dep_id", department.getId()));
                DeviceThree deviceThree = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().eq("dep_id",department.getId()));

                List<DeviceFoot> deviceFootList = deviceFootService.list(new QueryWrapper<DeviceFoot>().eq("dep_id", department.getId()));
                List<Integer> footIds = deviceFootList.stream().map(DeviceFoot::getId).collect(Collectors.toList());
                List<Integer> userFootIds = deviceFootList.stream().map(DeviceFoot::getUserId).collect(Collectors.toList());

                List<DeviceThree> deviceThreeList = deviceThreeService.list(new QueryWrapper<DeviceThree>().eq("dep_id", department.getId()));
                List<Integer> threeIds = deviceThreeList.stream().map(DeviceThree::getId).collect(Collectors.toList());
                List<Integer> userThreeIds = deviceThreeList.stream().map(DeviceThree::getUserId).collect(Collectors.toList());

                if (deviceFoot == null||deviceThree == null) {
                    if(deviceFoot== null&&deviceThree == null)
                    {
                        departmentService.removeByIds(departmentIds);
                        baseMapper.deleteById(orgId);
                    }
                    else if(deviceFoot == null)
                    {
                        deviceThreeService.removeByIds(threeIds);
                        aclUserService.removeByIds(userThreeIds);
                        departmentService.removeByIds(departmentIds);
                        baseMapper.deleteById(orgId);
                    }else{
                        deviceFootService.removeByIds(footIds);
                        aclUserService.removeByIds(userFootIds);
                        departmentService.removeByIds(departmentIds);
                        baseMapper.deleteById(orgId);
                    }
                } else {
                    //                   deviceThreeService.removeById(deviceThree.getId());//删除单个三维设备
                    deviceThreeService.removeByIds(threeIds);
                    aclUserService.removeByIds(userThreeIds);
                    //                   deviceFootService.removeById(deviceFoot.getId());//删除单个足底设备
                    deviceFootService.removeByIds(footIds);
                    aclUserService.removeByIds(userFootIds);
                    //                   departmentService.removeById(department.getId()); //删除单个科室
                    departmentService.removeByIds(departmentIds);
                    baseMapper.deleteById(orgId);
                }

            }
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException(20001, "Remove failed");
        }
    }
    @Override
    public R update(Map<String,Object> dataMap){
        dataMap.remove("departments");
        Organization organization= JSON.parseObject(JSON.toJSONString(dataMap),Organization.class);
        Integer count = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_Name",organization.getOrgName()).ne("id",organization.getId()));
        if (count >= 1) return R.error().message("该医院重名");
        Integer countTwo = baseMapper.selectCount(new QueryWrapper<Organization>().eq("org_Num",organization.getOrgNum()).ne("id",organization.getId()));
        if (countTwo >= 1) return R.error().message("该医院编号重名");
        int id = baseMapper.updateById(organization);
        if (id <= 0) R.error().message("添加失败，请重新操作");
        return R.ok();
    }
    @Override
    public R updatePicture(HttpServletRequest request) throws IOException {
        String orgId = request.getParameter("orgId");
        String orgName = request.getParameter("orgName");
        String orgNum = request.getParameter("orgNum");
        Organization organization = baseMapper.selectOne(new QueryWrapper<Organization>().eq("id", orgId));
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("orgIconPath");
        if(file!=null){
            Date date = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
            //获取上传图片的名称
            String orgIconPath = System.getProperty("user.dir")+ File.separator+filePathConfig.getOrgPictureDir()+File.separator+orgName+"_"+orgNum+File.separator+formatter.format(date)+File.separator+file.getOriginalFilename();
            File iconFile = new File(orgIconPath);
            if(!iconFile.exists())iconFile.mkdirs();//不存在的话，就开辟一个空间
            //将上传的文件存储
            file.transferTo(iconFile);
            organization.setOrgIconPath(orgIconPath);
        }
        baseMapper.updateById(organization);

        return R.ok().data("organization",organization);
    }
}
